package com.heima.reggie.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.reggie.bean.*;
import com.heima.reggie.dto.DishDto;
import com.heima.reggie.exception.CustomException;
import com.heima.reggie.mapper.DishMapper;
import com.heima.reggie.service.*;
import org.apache.commons.lang.StringUtils;
import org.omg.PortableServer.LIFESPAN_POLICY_ID;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class DishServiceImpl implements DishService {
    @Autowired
    private DishMapper mapper;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private SetmealService setmealService;

    @Autowired
    private RedisTemplate redisTemplate;

  /**
    * 根据分类id统计数量
    * @param cid
    * @param
    * @return
    */
    @Override
    public long findCpuntByCid(long cid) {
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Dish::getCategoryId, cid);
        return mapper.selectCount(lqw);
    }
/**
  * 分页查询
  * @param pageParam
  * @return IPage<DishDto>
  */
    @Override
    public IPage<DishDto> selectByPage(PageParam pageParam) {
        //设置分页数据
        IPage<Dish> page = new Page<>(pageParam.getPage(), pageParam.getPageSize());
        //设置查询条件
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.like(pageParam.getName()!=null,Dish::getName,pageParam.getName());
        //执行查询
        IPage<Dish> dishIPage = mapper.selectPage(page, lqw);
        //把查询的集合数据拿出来
        List<Dish> records = dishIPage.getRecords();
        //创建一个集合封装DishDto
        List<DishDto> dishDtoList=new ArrayList<>();
        //遍历集合数据
        for (Dish record : records) {
            //创建DishDto对象封装dish数据和categoryName
            DishDto dishDto=new DishDto();
            //根据categoryId查询categoryName,并封装到dishDto中
            Category category = categoryService.selectById(record.getCategoryId());
            dishDto.setCategoryName(category.getName());
            //根据dishId查询对应的口味数据，并封装到dishDto中
            List<DishFlavor> dishFlavors = dishFlavorService.selectByDid(record.getId());
            dishDto.setFlavors(dishFlavors);
            //把dish数据复制到dishDto中
            BeanUtils.copyProperties(record,dishDto);
            //把dishDto添加到dishDtoList集合中
            dishDtoList.add(dishDto);
        }
        //创建IPage<DishDto>，封装dishDtoIPage和Total
        IPage<DishDto> dishDtoIPage = new Page<>();
        dishDtoIPage.setRecords(dishDtoList);
        dishDtoIPage.setTotal(dishIPage.getTotal());
        return dishDtoIPage;
    }
/**
  * 添加菜品
  * @param dishDto
  * @param
  * @return insert
  */
    @Override
    public int add(DishDto dishDto) {
        //清理某个分类下面的菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        int insert = mapper.insert(dishDto);
        if (insert>0 && dishDto.getFlavors().size()>0) {
            int row=0;
            for (DishFlavor flavor : dishDto.getFlavors()) {
                flavor.setDishId(dishDto.getId());
                row+=dishFlavorService.add(flavor);
            }
            return row==dishDto.getFlavors().size()?2:0;
        }
        return insert;
    }
/**
  * 根据ids删除
  * @param ids
  * @param
  * @return
  */
    @Override
    public int deleteByIds(List<Long> ids) {
        //清理所有菜品的缓存数据
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        /*int i = mapper.deleteBatchIds(ids);
        //int i = mapper.deleteById(id);
        int row1=0;
        int row2=0;
        if (i > 0) {
            for (long id : ids) {
                row1+= dishFlavorService.countByDid(id);
                row2+= dishFlavorService.deleteByDid(id);
            }
            return row1==row2?2:0;
        }*/
        int row1=0;
        int row2=0;
        int row3=0;
        for (Long id : ids) {
            Dish dish = mapper.selectById(id);
            if (dish.getStatus()==1){
                throw new CustomException("菜品处于起售状态，无法删除！");
            }
            List<SetmealDish> setmealDishes = setmealDishService.selectByDid(id);
            if (setmealDishes != null && setmealDishes.size() > 0) {
                for (SetmealDish setmealDish : setmealDishes) {
                    Setmeal setmeal = setmealService.selectBySid(setmealDish.getSetmealId());
                    if (setmeal.getStatus() == 1) {
                        throw new CustomException("在售的套餐中含有将删除的菜品，无法删除！");
                    }
                }
            }
            row1+= mapper.deleteById(id);
            if (row1>0){
                row2+= dishFlavorService.countByDid(id);
                row3+= dishFlavorService.deleteByDid(id);
            }
            return row2==row3?2:0;

        }
        return row1==ids.size()?1:0;
    }
/**
  * 修改状态
  * @param status
  * @param ids
  * @return
  */
    @Override
    public int updateStatus(int status, List<Long> ids) {
        //清理所有菜品的缓存数据
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        Dish dish = new Dish();
        dish.setStatus(status);
        int row=0;
        for (Long id : ids) {
            dish.setId(id);
            row+= mapper.updateById(dish);
        }
        return row==ids.size()?1:0;
    }
/**
  * 修改菜品
  * @param dishDto
  * @param
  * @return
  */
    @Override
    public int updateDish(DishDto dishDto) {
        //清理某个分类下面的菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        int i = mapper.updateById(dishDto);
        if (i > 0) {

            int row1= dishFlavorService.countByDid(dishDto.getId());
            int row2= dishFlavorService.deleteByDid(dishDto.getId());
            int row3=0;
            if (row1 == row2 && dishDto.getFlavors() != null && dishDto.getFlavors().size() > 0) {
                for (DishFlavor flavor : dishDto.getFlavors()) {
                    flavor.setDishId(dishDto.getId());
                    row3+= dishFlavorService.add(flavor);
                }
                return row3==dishDto.getFlavors().size()?3:0;
            }
            else {
                return row1==row2?2:0;
            }

        }
        return i;
    }
/**
  * 根据分类id、name、status查询菜品列表
  * @param
  * @param
  * @return
  */
    @Override
    public List<DishDto> selectDishList(DishDto dishDto) {
       String key= "dish_" + dishDto.getCategoryId()+"_"+dishDto.getStatus();
        String o = (String) redisTemplate.opsForValue().get(key);
        if (StringUtils.isNotEmpty(o)) {
            System.out.println("redis里面有数据,直接返回"+dishDto.getCategoryId());
            List<DishDto> objects = JSON.parseArray(o,DishDto.class);
            return objects;
        }
        System.out.println("redis里面没有数据,去数据库查询"+dishDto.getCategoryId());
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(dishDto.getCategoryId()!=null,Dish::getCategoryId, dishDto.getCategoryId());
        lqw.like(dishDto.getName()!=null,Dish::getName,dishDto.getName());
        lqw.eq(dishDto.getStatus()!=null,Dish::getStatus,dishDto.getStatus());
        List<Dish> dishList = mapper.selectList(lqw);
        List<DishDto> dishDtoList = dishList.stream().map((dish) -> {
            DishDto dishDto1 = new DishDto();
            List<DishFlavor> dishFlavors = dishFlavorService.selectByDid(dish.getId());
            dishDto1.setFlavors(dishFlavors);
            BeanUtils.copyProperties(dish, dishDto1);
            return dishDto1;
        }).collect(Collectors.toList());
        redisTemplate.opsForValue().set(key, JSON.toJSONString(dishDtoList));
        return dishDtoList;
    }


}
